/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup Audio
 * @{
 *
 * @brief Audio模块接口定义
 *
 * 音频接口涉及自定义类型、驱动加载接口、驱动适配器接口、音频播放（render）接口、音频录音（capture）接口等
 *
 * @since 1.0
 * @version 1.0
 */

/**
 * @file audio_types.h
 *
 * @brief Audio模块接口定义中使用的自定义数据类型
 *
 * Audio模块接口定义中使用的自定义数据类型，包括音频端口、适配器描述符、设备描述符、场景描述符、采样属性、时间戳等
 *
 * @since 1.0
 * @version 1.0
 */

#ifndef AUDIO_TYPES_H
#define AUDIO_TYPES_H

#include <stdint.h>
#include <stdbool.h>

/**
 * @brief 音频句柄
 */
typedef void *AudioHandle;

/**
 * @brief 音频端口的类型
 */
enum AudioPortDirection {
    PORT_OUT    = 0x1u, /**< 音频输出端口 */
    PORT_IN     = 0x2u, /**< 音频输入端口 */
    PORT_OUT_IN = 0x3u, /**< 音频输出/入端口, 同时支持输出和输入能力（OUT | IN） */
};

/**
 * @brief 音频端口
 */
struct AudioPort {
    enum AudioPortDirection dir; /**< 音频端口的类型，详情参考{@link AudioPortDirection} */
    unsigned int portId;         /**< 音频端口的ID */
    const char *portName;        /**< 音频端口的名称 */
};

/**
 * @brief 音频适配器描述符
 *
 * 一个音频适配器（adapter）是一个声卡的端口驱动集合，包含输出端口、输入端口，
 * 其中一个端口对应着多个PIN脚，一个PIN脚对应着一个实体的器件（例如喇叭、有线耳机）
 */
struct AudioAdapterDescriptor {
    const char *adapterName; /**< 音频适配器的名称 */
    unsigned int portNum;    /**< 一个音频适配器支持的端口数目 */
    struct AudioPort *ports; /**< 一个音频适配器支持的端口列表 */
};

/**
 * @brief 音频适配器端口的PIN脚
 */
enum AudioPortPin {
    PIN_NONE        = 0x0u,       /**< 无效PIN */
    PIN_OUT_SPEAKER = 0x1u,       /**< 喇叭输出 */
    PIN_OUT_HEADSET = 0x2u,       /**< 有线耳机输出 */
    PIN_OUT_LINEOUT = 0x4u,       /**< Lineout输出 */
    PIN_OUT_HDMI    = 0x8u,       /**< HDMI输出 */
    PIN_OUT_USB     = 0x10u,      /**< USB设备输出 */
    PIN_OUT_USB_EXT = 0x20u,      /**< 扩展 USB 设备输出 */
    PIN_IN_MIC      = 0x8000001u, /**< Mic输入 */
    PIN_IN_HS_MIC   = 0x8000002u, /**< 有线耳机Mic输入 */
    PIN_IN_LINEIN   = 0x8000004u, /**< Linein输入 */
    PIN_IN_USB_EXT  = 0x8000008u, /**< 扩展 USB 设备输入 */
};

/**
 * @brief 音频设备描述符
 */
struct AudioDeviceDescriptor {
    unsigned int portId;    /**< 音频端口ID */
    enum AudioPortPin pins; /**< 音频端口上的PIN脚（输出、输入），详情参考{@link AudioPortPin} */
    const char *desc;       /**< 以字符串命名的音频设备 */
};

/**
 * @brief 音频类型（category）
 */
enum AudioCategory {
    AUDIO_IN_MEDIA = 0,     /**< 媒体 */
    AUDIO_IN_COMMUNICATION, /**< 通信 */
    AUDIO_IN_RINGTONE,      /**< 铃声 */
    AUDIO_IN_CALL,          /**< 呼叫 */
};

/**
 * @brief 音频场景描述符
 */
struct AudioSceneDescriptor {
    /**
     * @brief 音频场景描述
     */
    union SceneDesc {
        unsigned int id;               /**< 音频场景的ID */
        const char *desc;              /**< 以字符串命名的音频场景 */
    } scene;                           /**< 音频场景的名称 */
    struct AudioDeviceDescriptor desc; /**< 音频设备描述符 */
};

/**
 * @brief 音频格式
 */
enum AudioFormat {
    AUDIO_FORMAT_PCM_8_BIT  = 0x1u,       /**< 8bit位宽pcm格式 */
    AUDIO_FORMAT_PCM_16_BIT = 0x2u,       /**< 16bit位宽pcm格式 */
    AUDIO_FORMAT_PCM_24_BIT = 0x3u,       /**< 24bit位宽pcm格式 */
    AUDIO_FORMAT_PCM_32_BIT = 0x4u,       /**< 32bit位宽pcm格式 */
    AUDIO_FORMAT_AAC_MAIN   = 0x1000001u, /**< AAC MAIN格式 */
    AUDIO_FORMAT_AAC_LC     = 0x1000002u, /**< AAC LC格式 */
    AUDIO_FORMAT_AAC_LD     = 0x1000003u, /**< AAC LD格式 */
    AUDIO_FORMAT_AAC_ELD    = 0x1000004u, /**< AAC ELD格式 */
    AUDIO_FORMAT_AAC_HE_V1  = 0x1000005u, /**< AAC HE_V1格式 */
    AUDIO_FORMAT_AAC_HE_V2  = 0x1000006u, /**< AAC HE_V2格式 */
    AUDIO_FORMAT_G711A      = 0x2000001u, /**< G711A格式 */
    AUDIO_FORMAT_G711U      = 0x2000002u, /**< G711u格式 */
    AUDIO_FORMAT_G726       = 0x2000003u, /**< G726格式 */
};

/**
 * @brief 音频通道掩码（mask）
 *
 * 定义音频声道的位置
 */
enum AudioChannelMask {
    AUDIO_CHANNEL_FRONT_LEFT  = 0x1,  /**< 声道布局前左 */
    AUDIO_CHANNEL_FRONT_RIGHT = 0x2,  /**< 声道布局前右 */
    AUDIO_CHANNEL_MONO        = 0x1u, /**< 单声道 */
    AUDIO_CHANNEL_STEREO      = 0x3u, /**< 立体声，由左右声道组成（FRONT_LEFT | FRONT_RIGHT） */
};

/**
 * @brief 音频采样频率MASK
 */
enum AudioSampleRatesMask {
    AUDIO_SAMPLE_RATE_MASK_8000    = 0x1u,        /**< 8K 采样频率 */
    AUDIO_SAMPLE_RATE_MASK_12000   = 0x2u,        /**< 12K 采样频率 */
    AUDIO_SAMPLE_RATE_MASK_11025   = 0x4u,        /**< 11.025K 采样频率 */
    AUDIO_SAMPLE_RATE_MASK_16000   = 0x8u,        /**< 16K 采样频率 */
    AUDIO_SAMPLE_RATE_MASK_22050   = 0x10u,       /**< 22.050K 采样频率 */
    AUDIO_SAMPLE_RATE_MASK_24000   = 0x20u,       /**< 24K 采样频率 */
    AUDIO_SAMPLE_RATE_MASK_32000   = 0x40u,       /**< 32K 采样频率 */
    AUDIO_SAMPLE_RATE_MASK_44100   = 0x80u,       /**< 44.1K 采样频率 */
    AUDIO_SAMPLE_RATE_MASK_48000   = 0x100u,      /**< 48K 采样频率 */
    AUDIO_SAMPLE_RATE_MASK_64000   = 0x200u,      /**< 64K 采样频率 */
    AUDIO_SAMPLE_RATE_MASK_96000   = 0x400u,      /**< 96K 采样频率 */
    AUDIO_SAMPLE_RATE_MASK_INVALID = 0xFFFFFFFFu, /**< 无效的采样频率 */
};

/**
 * @brief 音频采样属性
 */
struct AudioSampleAttributes {
    enum AudioCategory type; /**< 音频类型，详情参考{@link AudioCategory} */
    bool interleaved;           /**< 音频数据交织的标记 */
    enum AudioFormat format;    /**< 音频数据格式，详情参考{@link AudioFormat} */
    unsigned int sampleRate;    /**< 音频采样频率 */
    uint32_t channelCount;   /**< 音频通道数目，如单通道（mono）为1、立体声（stereo）为2 */
    uint32_t period;           /**< 音频采样周期 */
    uint32_t frameSize;        /**< 音频数据的帧大小 */
    bool isBigEndian;          /**< 音频数据的大端标志 */
    bool isSignedData;         /**< 音频数据的有符号或无符号标志 */
    uint32_t startThreshold;   /**< 音频渲染开始阈值 */
    uint32_t stopThreshold;    /**< 音频渲染停止阈值 */
    uint32_t silenceThreshold; /**< 音频捕获缓冲区阈值 */
    int32_t streamId;          /**< 渲染或捕获的音频标识符 */
};

/**
 * @brief 音频时间戳
 *
 * 时间定义，POSIX timespec的替代品
 */
struct AudioTimeStamp {
    int64_t tvSec;  /**< tvSec时间，单位：秒 */
    int64_t tvNSec; /**< tvNSec时间，单位：纳秒 */
};

/**
 * @brief 音频端口的数据透传模式
 */
enum AudioPortPassthroughMode {
    PORT_PASSTHROUGH_LPCM    = 0x1, /**< 立体声pcm */
    PORT_PASSTHROUGH_RAW     = 0x2, /**< HDMI透传 */
    PORT_PASSTHROUGH_HBR2LBR = 0x4, /**< 蓝光次世代音频降规格输出 */
    PORT_PASSTHROUGH_AUTO    = 0x8, /**< 根据HDMI EDID能力自动匹配 */
};

/**
 * @brief 音频子端口的支持能力
 */
struct AudioSubPortCapability {
    unsigned int portId;                /**< 子端口ID */
    const char *desc;                   /**< 以字符串命名的子端口 */
    enum AudioPortPassthroughMode mask; /**< 数据透传模式，详情参考{@link AudioPortPassthroughMode} */
};

/**
 * @brief 原始音频样本格式
 */
enum AudioSampleFormat {
    /* 8 bits */
    AUDIO_SAMPLE_FORMAT_S8,   /**< 8bit位宽有符号交织样本 */
    AUDIO_SAMPLE_FORMAT_S8P,  /**< 8bit位宽有符号非交织样本 */
    AUDIO_SAMPLE_FORMAT_U8,   /**< 8bit位宽无符号交织样本  */
    AUDIO_SAMPLE_FORMAT_U8P,  /**< 8bit位宽无符号非交织样本 */
    /* 16 bits */
    AUDIO_SAMPLE_FORMAT_S16,  /**< 16bit位宽有符号交织样本 */
    AUDIO_SAMPLE_FORMAT_S16P, /**< 16bit位宽有符号非交织样本 */
    AUDIO_SAMPLE_FORMAT_U16,  /**< 16bit位宽无符号符号交织样本  */
    AUDIO_SAMPLE_FORMAT_U16P, /**< 16bit位宽无符号符号非交织样本 */
    /* 24 bits */
    AUDIO_SAMPLE_FORMAT_S24,  /**< 24bit位宽有符号交织样本 */
    AUDIO_SAMPLE_FORMAT_S24P, /**< 24bit位宽有符号非交织样本 */
    AUDIO_SAMPLE_FORMAT_U24,  /**< 24bit位宽无符号符号交织样本  */
    AUDIO_SAMPLE_FORMAT_U24P, /**< 24bit位宽无符号非交织样本 */
    /* 32 bits */
    AUDIO_SAMPLE_FORMAT_S32,  /**< 32bit位宽有符号交织样本 */
    AUDIO_SAMPLE_FORMAT_S32P, /**< 32bit位宽有符号非交织样本 */
    AUDIO_SAMPLE_FORMAT_U32,  /**< 32bit位宽无符号交织样本  */
    AUDIO_SAMPLE_FORMAT_U32P, /**< 32bit位宽无符号非交织样本 */
    /* 64 bits */
    AUDIO_SAMPLE_FORMAT_S64,  /**< 64bit位宽有符号交织样本 */
    AUDIO_SAMPLE_FORMAT_S64P, /**< 64bit位宽有符号非交织样本 */
    AUDIO_SAMPLE_FORMAT_U64,  /**< 64bit位宽无符号交织样本  */
    AUDIO_SAMPLE_FORMAT_U64P, /**< 64bit位宽无符号非交织样本 */
    /* float double */
    AUDIO_SAMPLE_FORMAT_F32,  /**< 32bit位宽浮点型交织样本 */
    AUDIO_SAMPLE_FORMAT_F32P, /**< 64bit位宽浮点型非交织样本 */
    AUDIO_SAMPLE_FORMAT_F64,  /**< 64bit位宽双精度浮点型交织样本  */
    AUDIO_SAMPLE_FORMAT_F64P, /**< 64bit位宽双精度浮点型非交织样本 */
};

/**
 * @brief 音频端口的支持能力
 */
struct AudioPortCapability {
    unsigned int deviceType;                 /**< 设备输出、输入类型 */
    unsigned int deviceId;                   /**< 绑定（bind）设备ID，唯一的设备识别符 */
    bool hardwareMode;                       /**< 是否支持设备绑定处理 */
    unsigned int formatNum;                  /**< 支持的音频格式数目 */
    enum AudioFormat *formats;               /**< 支持的音频格式，详情参考{@link AudioFormat} */
    unsigned int sampleRateMasks;            /**< 支持的音频采样频率（8k、16k、32k、48k） */
    enum AudioChannelMask channelMasks;      /**< 设备的声道布局掩码（mask），详情参考{@link AudioChannelMask} */
    unsigned int channelCount;               /**< 支持的最大声道总数 */
    unsigned int subPortsNum;                /**< 支持的子端口数目（仅用于输出设备） */
    struct AudioSubPortCapability *subPorts; /**< 支持的子端口列表 */
    uint32_t supportSampleFormatNum;         /**< 支持的音频样本格式数量 */
    enum AudioSampleFormat *supportSampleFormats; /**< 支持的音频样本格式，详请参考{@link AudioSampleFormat} */
};

/**
 * @brief 音频播放的通道模式
 *
 * @attention 下面的模式是针对双通道立体声的音频播放而设置，其他不支持
 */
enum AudioChannelMode {
    AUDIO_CHANNEL_NORMAL = 0, /**< 正常模式，不做处理 */
    AUDIO_CHANNEL_BOTH_LEFT,  /**< 两个声道全部为左声道声音 */
    AUDIO_CHANNEL_BOTH_RIGHT, /**< 两个声道全部为右声道声音 */
    AUDIO_CHANNEL_EXCHANGE,   /**< 左右声道数据互换，左声道为右声道声音，右声道为左声道声音 */
    AUDIO_CHANNEL_MIX,        /**< 左右两个声道输出为左右声道相加（混音） */
    AUDIO_CHANNEL_LEFT_MUTE,  /**< 左声道静音，右声道播放原右声道声音 */
    AUDIO_CHANNEL_RIGHT_MUTE, /**< 右声道静音，左声道播放原左声道声音 */
    AUDIO_CHANNEL_BOTH_MUTE,  /**< 左右声道均静音 */
};

/**
 * @brief DrainBuffer函数结束类型
 */
enum AudioDrainNotifyType {
    AUDIO_DRAIN_NORMAL_MODE, /**< DrainBuffer在所有数据播放结束后返回 */
    AUDIO_DRAIN_EARLY_MODE,  /**< DrainBuffer()在当前曲目的所有数据播放完之前返回，以便留出时间给音频服务做连续性曲目切换 */
};

/**
 * @brief 回调函数通知事件类型
 */
enum AudioCallbackType {
    AUDIO_NONBLOCK_WRITE_COMPELETED, /**< 非阻塞式写完成 */
    AUDIO_DRAIN_COMPELETED,          /**< DrainBuffer完成 */
    AUDIO_FLUSH_COMPLETED,           /**< Flush完成 */
    AUDIO_RENDER_FULL,               /**< Render缓冲区已满 */
    AUDIO_ERROR_OCCUR,               /**< 发生了错误 */
};

/**
 * @brief mmap缓冲区描述符
 */
struct AudioMmapBufferDescripter {
    void *memoryAddress;                 /**< 指向mmap缓冲区的指针 */
    int32_t memoryFd;                    /**< mmap缓冲区的文件描述符 */
    int32_t totalBufferFrames;           /**< 缓冲区总大小，单位：帧 */
    int32_t transferFrameSize;           /**< 传输大小，单位：帧 */
    int32_t isShareable;                 /**< mmap缓冲区是否可以在进程间共享 */
};

/**
 * @brief 音频端口角色
 */
enum AudioPortRole {
    AUDIO_PORT_UNASSIGNED_ROLE = 0, /**< 未指定端口角色 */
    AUDIO_PORT_SOURCE_ROLE = 1,     /**< 指定端口为发送端角色 */
    AUDIO_PORT_SINK_ROLE = 2,       /**< 指定端口为接受端角色 */
};

/**
 * @brief 音频端口类型.
 */
enum AudioPortType {
    AUDIO_PORT_UNASSIGNED_TYPE = 0, /**< 未指定端口类型 */
    AUDIO_PORT_DEVICE_TYPE = 1,     /**< 指定端口为设备类型 */
    AUDIO_PORT_MIX_TYPE = 2,        /**< 指定端口类型为复合类型 */
    AUDIO_PORT_SESSION_TYPE = 3,    /**< 指定端口为会话类型 */
};

/**
 * @brief 音频设备拓展信息.
 */
struct AudioDevExtInfo {
    int32_t moduleId;       /**< 音频流绑定的模块ID */
    enum AudioPortPin type; /**< 音频端口上的PIN脚（输出、输入），详情参考{@link AudioPortPin} */
    const char *desc;       /**< 地址描述  */
};

/**
 * @brief 音轨拓展信息
 */
struct AudioMixExtInfo {
    int32_t moduleId;     /**< 流所属模块标识符 */
    int32_t streamId;     /**< 由调用者传递的Render或Capture标识符 */
};

/**
 * @brief 端口会话类型
 */
enum AudioSessionType {
    AUDIO_OUTPUT_STAGE_SESSION = 0, /**< 会话绑定到指定输出流 */
    AUDIO_OUTPUT_MIX_SESSION,       /**< 会话绑定到特定音轨 */
    AUDIO_ALLOCATE_SESSION,         /**< 会话ID需重新申请 */
    AUDIO_INVALID_SESSION,          /**< 无效会话类型 */
};

/**
 * @brief 会话拓展信息
 * @see AudioSessionType
 */
struct AudioSessionExtInfo {
    enum AudioSessionType sessionType;  /**< 音频会话类型 */
};

/**
 * @brief 音频路由节点.
 * @see AudioPortRole
 * @see AudioPortType
 * @see AudioDevExtInfo
 *
 */
struct AudioRouteNode {
    int32_t portId;                      /**< 音频端口ID */
    enum AudioPortRole role;             /**< 指定端口角色为sink或source */
    enum AudioPortType type;             /**< 指定端口类型为device, mix ... */
    union {
        struct AudioDevExtInfo device;   /* 设备特定信息 */
        struct AudioMixExtInfo mix;      /* 音轨特定信息 */
        struct AudioSessionExtInfo session; /* 会话特定信息 */
    } ext;
};

/**
 * @brief 音频路由信息.
 */
struct AudioRoute {
    uint32_t sourcesNum;                    /**< 发送端节点数量 */
    const struct AudioRouteNode *sources;   /**< 发送端列表 */
    uint32_t sinksNum;                      /**< 接受端节点数量 */
    const struct AudioRouteNode *sinks;     /**< 接受端列表 */
};

/**
 * @brief 回调函数指针
 *
 * @param AudioCallbackType 回调函数响应类型
 * @param reserved 保留字段
 * @param cookie 用于传递数据
 * @return 成功返回值0，失败返回负值
 * @see RegCallback
 */
typedef int32_t (*RenderCallback)(enum AudioCallbackType, void *reserved, void *cookie);

#endif /* AUDIO_TYPES_H */
